package com.kichina.parking.utils;

import com.alibaba.fastjson.JSONObject;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Surging
 * @version 1.0
 * @ClassName JsonToEntityUtil
 * @date 2022-06-21 16:58
 * @desc JSONObject转换为实体
 */
public class JsonToEntityUtil {
    public static final char UNDERLINE_CHAR = '_';

    /**
     * @param camelStr 输入字符串
     * @author Surging
     * @Description 驼峰转下划线大写
     * @Return java.lang.String
     * @date 16:04 2022-09-14
     **/
    public static String camelUnderline(String camelStr) {
        if (org.apache.commons.lang.StringUtils.isEmpty(camelStr)) {
            return org.apache.commons.lang.StringUtils.EMPTY;
        }
        int len = camelStr.length();
        StringBuilder strb = new StringBuilder(len + len >> 1);
        for (int i = 0; i < len; i++) {
            char c = camelStr.charAt(i);
            if (Character.isUpperCase(c)) {
                strb.append(UNDERLINE_CHAR);
                strb.append(Character.toLowerCase(c));
            } else {
                strb.append(c);
            }
        }
        return strb.toString().toUpperCase();
    }

    /**
     * @param jsonObject  JSONObject对象
     * @param classType JavaBean类型
     * @author Surging
     * @Description 将JSON对象中的数据封装到JavaBean中，带下划线的key
     * @Return T
     * @date 16:05 2022-09-14
     **/
    public static <T> T jsonToEntity(JSONObject jsonObject, Class<T> classType) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //采用反射机制创建对象
        T entity = classType.newInstance();
        //获取对象字节码信息，不要Object的属性
        BeanInfo beanInfo = Introspector.getBeanInfo(classType, Object.class);
        //获取entity对象中的所有属性
        PropertyDescriptor[] list = beanInfo.getPropertyDescriptors();
        for (String next : jsonObject.keySet()) {
            label:
            for (PropertyDescriptor pd : list) {
                //获取属性名
                String key = pd.getName();
                if (next.equalsIgnoreCase(key) || next.equalsIgnoreCase(camelUnderline(key)) || key.equalsIgnoreCase(next.replace("_", ""))) {
                    //获取属性值
                    Class<?> propertyType = pd.getPropertyType();
                    switch (propertyType.toString()) {
                        case "int":
                        case "class java.lang.Integer": {
                            String string = jsonObject.getString(next);
                            if (!org.apache.commons.lang.StringUtils.isEmpty(string) && !"".equals(string)) {
                                Integer value = Integer.valueOf(string);
                                pd.getWriteMethod().invoke(entity, value);
                            }
                            break label;
                        }
                        case "class java.math.BigDecimal": {
                            String string = jsonObject.getString(next);
                            if (!org.apache.commons.lang.StringUtils.isEmpty(string) && !"".equals(string)) {
                                BigDecimal value = BigDecimal.valueOf(Double.parseDouble(string));
                                pd.getWriteMethod().invoke(entity, value);
                            }
                            break label;
                        }
                        case "class java.util.Date": {
                            String string = jsonObject.getString(next);
                            if (!org.apache.commons.lang.StringUtils.isEmpty(string) && !"".equals(string)) {
                                Date parse = sdf.parse(string);
                                pd.getWriteMethod().invoke(entity, parse);
                            }
                            break label;
                        }
                        default:
                            if (!"tmark".equalsIgnoreCase(next) && !"lg_lock".equalsIgnoreCase(next)) {
                                String value = jsonObject.getString(next);
                                pd.getWriteMethod().invoke(entity, value);
                                break label;
                            }
                            break;
                    }
                }
            }
        }
        return entity;
    }

}
